'''
1、概念：python的一种单元测试框架，比 UnitTest 更简洁、效率更高
        pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytest
2、特点：
      易上手，文档丰富
      支持简单的单元测试、复杂的功能测试
      支持参数化  (unitTest 需要插件 parameterized 扩展参数化功能）
      执行测试过程中，可跳过某些测试，或对某些预期失败的 case 标记失败
      支持重复执行失败的 case （安装插件实现）
      执行运行由 Nose、UnitTest 编写的 case （pytest的脚本在 unittest下无法执行）
      具有很多第三方插件，并可自定义扩展
      方便的和持续集成工具集成
3、基本使用：
           ① 测试类形式：
                          代码：
                               （test_login.py）
                                    class TestLogin(object):          测试类必须以 Test 开头
                                        def test_a(self):             测试方法名必须以 test 开头
                                           print("-----> test_a")
                                           asert 1   断言成功
                                        def test_b(self):
                                           print("-----> test_b")
                                           asert 0   断言失败
                          运行方式：
                                 命令行： pytest -s test_login.py
                                 主函数：在 test_login.py 中增加主函数
                                           if __name__="__main__":
                                               pytest.main(["-s", "test_login.py"])       -s：输出打印信息
           ② 测试函数形式：
                          代码：
                              def test_func(self):                   测试函数必须以 test 开头
                                 print("测试函数")
                          运行方式：如上
           ③  特殊方法：
                      说明：
                          特殊方法名写法固定，没有代码提示，需要手写
                          函数级别执行顺序： setup -> 测试方法 -> teardown
                      类型：
                           函数级别：
                                   setup_method：   执行脚本之前会执行 setup    方法，可以在 setup    中进行获取驱动对象的操作
                                   teardown_method：执行脚本之后会执行 teardown 方法，可以在 teardown 中进行关闭驱动对象的操作
                           类级别：
                                   setup：   执行脚本之前会执行 setup    方法，可以在 setup    中进行获取驱动对象的操作
                                   teardown：执行脚本之后会执行 teardown 方法，可以在 teardown 中进行关闭驱动对象的操作
           ④ 配置文件：
                     应用场景：
                             使用配置文件后，可以快速的使用配置的项来选择执行哪些测试模块
                     操作：
                         命令行： pytest --help  (从下往上翻，查看 [pytest] ini-options。。。)
                         new - file - pytest.ini
                               [pytest]                                                        告知系统该文件的类型
                               testpaths = ./pytest_case                                       指定测试用例存放位置
                               addopts = -s                                                    添加 pytest 命令选项
                                         --html=./report/test_report.html --self-contained-html
                                         --reruns n
                               python_files = test*.py                                         指定测试脚本文件名前缀
                               python_classes = Test                                           指定测试类名前缀
                               python_functions = test                                         指定测试函数/测试方法名前缀
                     注意：
                         在 windows 系统下，pytest 配置文件中，不允许写注释信息
                         一个工程内，只需一个 pytest 配置文件，并需保证文件名正确
                         一般情况下，只需将 pytest 配置文件，置于工程的根目录下
                         配置有 pytest 配置文件的工程，只需打开命令行，输入 pytest 指令，即可执行测试
4、常用插件：
          ① 测试报告：
                     安装：pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytest-html
                             或：file - setting - project:demo- python interpreter - "+" - 搜索 - install package
                     配置： addopts = -s
                                     --html=./test_report.html --self-contained-html
          ② 控制函数执行顺序：
                          安装：pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytest-ordering
                          使用：
                              class TestDemo(object):
                                   @pytest.mark.run(order=2)
                                   def test_method1(self):

                                   @pytest.mark.run(order=1)
                                   def test_method2(self):
                          注意：run(order=序号)没有代码提示，需要手写
                               序号支持正负数：
                                           纯正数：数越小，优先级越高，先执行
                                           纯负数：数越小，优先级越高，先执行
                                           正负混合：正数先执行
                               对测试类、测试方法均有效
          ③ 失败重试：
                    安装：pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytest-rerunfailures
                    应用场景：
                           自动化测试脚本可能会使用网络，网络不好可能导致脚本不通过，可以使用失败重试插件，再次运行。
                    配置：addopts = -s
                                   --reruns n   (n：次数，一般最多3次，测试一般1次)
5、高级用法：
          ① 跳过测试函数：
                       class TestDemo(object):
                           @pytest.mark.skipif(version >= 25, reason="当前版本不执行")        符合条件、跳过原因
                           def test_method2(self):
          ② 参数化：
                  单个参数：
                          @pytest.mark.parametrize("name", ["小明", "小张"])             装饰器和方法中的name名称必须一一对应
                          def test_method(self, name):
                  多个参数：
                          @pytest.mark.parametrize("name, age", [("小明", 17), ("小刚", 19)])        [[], []] 或  [(), ()]
                          def test_method(self, name):
          ③ 通过函数/方法引入测试数据：
                                  @pytest.mark.parametrize("username, password, code", build_data())
                                  def test_method(self, username, password, code):
          ④ 断言：
                 assert 1 == 1                                （没有提示-断言通过，AssertionError-断言失败）
                 assert "admin" in "欢迎 admin 归来"
'''